#pragma once
#include <vector>
#include "mysql.hpp"
#include "logger.hpp"
#include "chat_session.hxx"
#include "chat_session-odb.hxx"

namespace zzy_mims
{
    class ChatSessionTable
    {
    public:
        using ptr = std::shared_ptr<ChatSessionTable>;
        ChatSessionTable(const std::shared_ptr<odb::core::database>& db):_db(db){};
        bool insert(ChatSession& cs)
        {
            try
            {
                odb::transaction trans(_db->begin());
                _db->persist(cs);
                trans.commit();
            }catch(std::exception& e)
            {
                LOG_ERROR("新增会话失败{}:{}",cs.chat_session_name(),e.what());
                return false;
            }
            return true;
        }
        bool remove(const std::string& sid)
        {
            try
            {

                odb::transaction trans(_db->begin());
                _db->erase_query<ChatSession>(odb::query<ChatSession>::chat_session_id==sid);
                _db->erase_query<SessionMember>(odb::query<SessionMember>::session_id==sid);
                trans.commit();
            }catch(std::exception& e)
            {
                LOG_ERROR("删除会话失败,{}:{}",sid,e.what());
                return false;
            }
            return true;
        }
        //删除单聊会话
        bool remove(const std::string& sender_id,const std::string& accepter_id)
        {
            try
            {
                using query = odb::query<SingleChatSession>;
                using result = odb::result<SingleChatSession>;
                odb::transaction trans(_db->begin());
                auto res = _db->query_one<SingleChatSession>(query::sm1::user_id==sender_id
                    &&query::sm2::user_id==accepter_id);
                std::string sid = res->sid;
                _db->erase_query<ChatSession>(odb::query<ChatSession>::chat_session_id==sid);
                _db->erase_query<SessionMember>(odb::query<SessionMember>::session_id==sid);
                trans.commit();
            }catch(std::exception& e)
            {
                LOG_ERROR("删除单聊会话失败,{}-{}:{}",sender_id,accepter_id,e.what());
                return false;
            }
            return true;
        }
        
        std::shared_ptr<ChatSession> select(const std::string& sid)
        {
            std::shared_ptr<ChatSession> ret;
            try
            {
                odb::transaction trans(_db->begin());
                ret.reset(_db->query_one<ChatSession>(odb::query<ChatSession>::chat_session_id==sid));
                trans.commit();
            }catch(std::exception& e)
            {
                LOG_ERROR("通过会话id获得会话信息失败,{}:{}",sid,e.what());
            }
            return ret;
        }
        //根据用户id获得包含这个用户的所有单聊信息
        std::vector<SingleChatSession> singleChatSession(const std::string& uid) 
        {
            std::vector<SingleChatSession> ret;
            try
            {
                odb::transaction trans(_db->begin());
                
                odb::result<SingleChatSession> r(_db->query<SingleChatSession>(odb::query<SingleChatSession>::sm1::user_id==uid));
                for(auto e:r)
                ret.emplace_back(e);
                
                trans.commit();
            }catch(std::exception& e)
            {
                LOG_ERROR("通过用户id获得所有单聊会话信息失败,{}:{}",uid,e.what());
            }
            return ret;
        }
        //根据用户id获得包含这个用户的所有群聊信息
        std::vector<GroupChatSession> groupChatSession(const std::string& uid)
        {
            std::vector<GroupChatSession> ret;
            try
            {
                odb::transaction trans(_db->begin());
                
                odb::result<GroupChatSession> r(_db->query<GroupChatSession>(odb::query<GroupChatSession>::sm::user_id==uid));
                for(auto e:r)
                ret.emplace_back(e);
                
                trans.commit();
            }catch(std::exception& e)
            {
                LOG_ERROR("通过用户id获得所有群聊会话信息失败,{}:{}",uid,e.what());
            }
            return ret;
        }



    private:
        std::shared_ptr<odb::core::database> _db;
    };
}